package cn.getech.data.metadata.model.excel;

import cn.getech.data.metadata.annotation.ExplicitConstraint;
import cn.getech.data.metadata.constant.YesOrNoEnum;
import cn.getech.data.metadata.entity.meta.CollectionTableField;
import cn.getech.data.metadata.entity.meta.CollectionTableInfo;
import cn.getech.data.metadata.utils.MapUtils;
import com.alibaba.excel.annotation.ExcelIgnore;
import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.annotation.write.style.ColumnWidth;
import com.alibaba.excel.annotation.write.style.HeadFontStyle;
import lombok.Data;
import org.apache.commons.lang.StringUtils;

import javax.validation.constraints.NotBlank;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

@Data
public class CollectionTableFieldExcel {


    /**
     * 数据库名称
     */
    @ExcelProperty(value = {"*数据库名称"}, order = 1)
    @NotBlank(message = "库不能为空")
    @HeadFontStyle(color = 10)//red
    @ExplicitConstraint(desc = "必填项，值只能包含字母,数字,下划线")
    @ColumnWidth(16)
    protected String dbName;

    /**
     * 表名称
     */
    @ExcelProperty(value = "*表名称",order =5)
    @NotBlank(message = "表不能为空")
    @HeadFontStyle(color = 10)//red
    @ExplicitConstraint(desc = "必填项，值只能包含字母,数字,下划线，同一数据库的表名称相同则判断为同一表")
    @ColumnWidth(14)
    private String tableName;

    /**
     * 表别名
     */
    @ExcelProperty(value = "表别名",order =10)
    @ExplicitConstraint(desc = "非必填项")
    @HeadFontStyle(color = 0)
    @ColumnWidth(14)
    private String tableAlias;


    /**
     * 字段名称
     */
    @ExcelProperty(value = "*字段名称",order =11)
    @ColumnWidth(14)
    @HeadFontStyle(color = 10)//red
    @ExplicitConstraint(desc = "必填项，值为字母数字下划线组合")
    @NotBlank(message = "字段不能为空")
    private String fieldName;

    /**
     * 字段类别
     */
    @ExcelProperty(value = "*字段类型", order = 12)
    @NotBlank(message = "字段类型不能为空")
    @HeadFontStyle(color = 10)//red
    @ExplicitConstraint(sourceClass = ExplicitFileType.class, desc = "必填项，值为字母组合")
    @ColumnWidth(14)
    private String fieldType;

    /**
     * 字段的描述
     */
    @ExcelProperty(value = "字段的描述",order =13)
    @ColumnWidth(14)
    @HeadFontStyle(color = 0)
    @ExplicitConstraint(desc = "非必填项")
    private String fieldDesc;

    /**
     * 是否临时表 1 是,0 否
     */
    @ExcelProperty(value = "是否临时表\n(1是,0否)",order =14)
    @ColumnWidth(14)
    @HeadFontStyle(color = 0)
    @ExplicitConstraint(source = {"0","1"},desc = "非必填，值仅为0或1，默认0，")
    private Integer tempFlag;

    /**
     * 表数据行数
     */
    @ExcelProperty(value = "表数据行数",order =15)
    @ColumnWidth(14)
    @HeadFontStyle(color = 0)
    @ExplicitConstraint(desc = "非必填项，值为数字，默认0")
    private Long rowsNum;

    /**
     * 表的大小
     */
    @ExcelProperty(value = "表的大小\n(单位：b)",order =20)
    @ColumnWidth(14)
    @HeadFontStyle(color = 0)
    @ExplicitConstraint(desc = "非必填项，值为数字，描述当前表已经存储的数据大小，单位为字节，默认0")
    private Double totalSize;

    /**
     * 是否分区  1 是,0 否
     */
    @ExcelProperty(value = "是否分区\n(1是,0否)",order =26)
    @ExplicitConstraint(source = {"0","1"},desc = "非必填，默认0，值仅为0或1")
    @HeadFontStyle(color = 0)
    @ColumnWidth(14)
    private Integer isPartition;
    /**
     * 详情信息
     */
    @ExcelProperty(value = "表描述",order =30)
    @ExplicitConstraint(desc = "非必填项")
    @HeadFontStyle(color = 0)
    @ColumnWidth(30)
    private String tableDesc;

    @ExcelIgnore
    private boolean changeFlag = false;

    public String getUniqueTable() {
        return dbName+"_"+tableName;
    }

    public CollectionTableInfo toToTable(CollectionTableInfo table) {
        if (table == null) {
            table = new CollectionTableInfo();
            table.setViewCount(0);
        }
        table.setId(table.getId());
        table.setDbName(this.dbName);
        table.setTableName(this.tableName);
        table.setTableAlias(this.tableAlias);
        rowsNum = rowsNum == null ? 0 : rowsNum;
        table.setRowsNum(this.rowsNum);
        table.setDeleteFlag(YesOrNoEnum.NO.getValue());
        table.setTempFlag(this.tempFlag);
        totalSize = totalSize == null ? 0 : totalSize;
        table.setTotalSize(this.totalSize);
        table.setTableDesc(this.tableDesc);
        return table;
    }


    private String changeInfo(String pre,String oldValue,String newValue){
        oldValue = oldValue == null ? "" : oldValue;
        newValue = newValue == null ? "" : newValue;
        if (oldValue.equals(newValue)) {
            return "";
        } else {
            changeFlag = true;
            return pre + oldValue + "->" + newValue;
        }
    }

    public CollectionTableField toField(Integer tableId, CollectionTableField field) {
        if (field == null) {
            field = new CollectionTableField();
        }else {
            String typeInfo = changeInfo("", field.getFieldType(), this.fieldType);
            String partInfo = changeInfo(StringUtils.isEmpty(typeInfo) ? "是否分区:" : ",是否分区:", (YesOrNoEnum.YES.getValue().equals(field.getIsPartition()) ? "是" : "否"),
                    (YesOrNoEnum.YES.getValue().equals(this.isPartition) ? "是" : "否"));
            String desc = changeInfo(StringUtils.isEmpty(typeInfo+partInfo) ? "描述:" : ",描述:", field.getFieldDesc(),
                    this.fieldDesc);
            String change = field.getFieldName() + "(" + typeInfo + partInfo + desc + ")";
            field.setChangeInfo(change);
        }
        field.setId(field.getId());
        field.setTableId(tableId);
        field.setIsPartition(this.isPartition);
        field.setFieldDesc(this.fieldDesc);
        field.setFieldName(this.fieldName);
        field.setDeleteFlag(YesOrNoEnum.NO.getValue());
        field.setFieldType(this.fieldType);
        return field;
    }

    public String validateValue() {
        String res = "";
        if (dbName.length() > 100) {
            res = res + "数据库长度不能超过100";
        }
        //字母数字下划线组合
        if (!tableName.matches("[A-Za-z0-9_]+")) {
            res = res + "值只能包含字母,数字,下划线";
        }
        if (tableName.length() > 200) {
            res = res + "表名长度不能超过200";
        }
        if (tableDesc != null && tableDesc.length() > 200) {
            res = res + "表描述长度不能超过200";
        }
        if (fieldName != null && fieldName.length() > 200) {
            res = res + "字段名长度不能超过200";
        }
        if (fieldDesc != null && fieldDesc.length() > 200) {
            res = res + "字段描述长度不能超过200";
        }
        if (totalSize != null && totalSize < 0) {
            res = res + "表大小不能为负数";
        }
        if (rowsNum != null && rowsNum < 0) {
            res = res + "表行数必须大于0";
        }
        Map<Integer, String[]> explicitListConstraintMap = MapUtils.explicitSource(getClass());
        if (explicitListConstraintMap.get(5) != null) {
            Set<String> types = new HashSet<>(Arrays.asList(explicitListConstraintMap.get(5)));
            if (!types.contains(fieldType.toUpperCase())) {
                res = "字段类型:[" + fieldType + "]";
            }
        }
        if (explicitListConstraintMap.get(7) != null) {
            Set<String> types = new HashSet<>(Arrays.asList(explicitListConstraintMap.get(7)));
            if (!types.contains(tempFlag + "")) {
                res = res + " 是否临时表:[" + tempFlag + "]";
            }
        }
        if (explicitListConstraintMap.get(10) != null) {
            Set<String> types = new HashSet<>(Arrays.asList(explicitListConstraintMap.get(10)));
            if (!types.contains(isPartition + "")) {
                res = res + " 是否分区字段:[" + isPartition + "]";
            }
        }

        return res;
    }

    /**
     * 保存数据顺序
     */
    @ExcelIgnore
    private Integer order=1;

    private static final long serialVersionUID = 1L;

}